package org.l.mybatis.core.sqlsource;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.Configuration;
import org.l.mybatis.core.annotation.SqlsourceDelete;
import org.l.mybatis.core.exception.MethodDefineException;
import org.l.mybatis.core.exception.SqlsourceBuilderException;
import org.l.mybatis.core.handler.ObjectHandler;

/**
 * Created by 严秋旺 on 2017/7/30.
 */
public class SqlsourceBuilderDelete extends SqlsourceBuilderAbstract implements SqlsourceBuilder {
    private final SqlCommandType sqlCommandType = SqlCommandType.DELETE;
    private SqlsourceDelete sqlsourceDelete;

    public SqlsourceBuilderDelete(Configuration configuration, Class<?> type, Method method,
            SqlsourceDelete sqlsourceDelete) throws MethodDefineException {
        super(configuration, type, method);
        this.sqlsourceDelete = sqlsourceDelete;
        analysis();
    }

    private void analysis() throws MethodDefineException {
        Class<?>[] paramTypes = this.method.getParameterTypes();
        this.paramCount = paramTypes.length;

        if (paramCount == 0) {
            throw new MethodDefineException("缺少表映射对象参数:" + method);
        } else if (paramCount == 1) {
        } else {
            throw new MethodDefineException("只能接受一个表映射对象参数:" + method);
        }

    }

    @Override
    public SqlCommandType getSqlCommandType() {
        return sqlCommandType;
    }

    @Override
    public BoundSql getBoundSql(Object parameterObject) {
        List<ParameterMapping> parameterMappings = new ArrayList<>();
        try {
            String sql = createSql(parameterObject, parameterMappings);
            BoundSql boundSql = new BoundSql(this.configuration, sql, parameterMappings, parameterObject);
            return boundSql;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private String createSql(Object parameterObject, List<ParameterMapping> parameterMappings) {
        MetaObject metaObject = SystemMetaObject.forObject(parameterObject);
        Class<?> paramType = metaObject.getOriginalObject().getClass();
        ObjectHandler objectHandler = ObjectHandler.create(paramType);

        StringBuilder delete = new StringBuilder(10);
        delete.append("delete from ").append(objectHandler.getTableName());

        int size = parameterMappings.size();
        String where = createWhere(null, parameterMappings, metaObject, objectHandler.getPrimaryFields());

        if (parameterMappings.size() > size || sqlsourceDelete.force()) {
            return delete + where;
        } else {
            throw new SqlsourceBuilderException("sql语句执行终止，因为没有删除条件，即将执行全表删除，如果要强制执行请设置@SqlsourceDelete的force为true");
        }
    }
}
